﻿using System;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace TSharp.Core.Aop.Handler
{
	/// <summary>
	/// 异常的处理类
	/// </summary>
	public class ExceptionCallHandler : ICallHandler
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="ExceptionCallHandler"/> class.
		/// </summary>
		/// <param name="messageTemplate">The message template.</param>
		/// <param name="policyName">Name of the policy.</param>
		/// <param name="order">The order.</param>
		public ExceptionCallHandler(string messageTemplate, string policyName, int order)
		{
			MessageTemplate = messageTemplate;
			PolicyName = policyName;
			Order = order;
		}

		/// <summary>
		/// 错误消息模板
		/// </summary>
		public string MessageTemplate { get; set; }

		/// <summary>
		/// Policy名称
		/// </summary>
		public string PolicyName { get; set; }

		#region ICallHandler Members

		/// <summary>
		/// Order in which the handler will be executed
		/// </summary>
		/// <value></value>
		public int Order { get; set; }

		/// <summary>
		/// Implement this method to execute your handler processing.
		/// </summary>
		/// <param name="input">Inputs to the current call to the target.</param>
		/// <param name="getNext">Delegate to execute to get the next delegate in the handler
		/// chain.</param>
		/// <returns>Return value from the target.</returns>
		public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
		{
			IMethodReturn result = getNext()(input, getNext);
			if (result.Exception != null)
			{
				string message = MessageTemplate.Replace("{Message}", result.Exception.Message)
					.Replace("{Source}", result.Exception.Source)
					.Replace("{StackTrace}", result.Exception.StackTrace)
					.Replace("{HelpLink}", result.Exception.HelpLink)
					.Replace("{TargetSite}", result.Exception.TargetSite.ToString());
				var ex = new Exception(message, result.Exception);
				bool rethrow = ExceptionPolicy.HandleException(ex, PolicyName);
				if (rethrow)
					throw result.Exception;
			}
			return result;
		}

		#endregion
	}
}